package cn.com.pajx.pajx_visitor_v3.utils;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.YuvImage;

import com.pajx.facelibrary.view.CameraPreviewManager;

import java.io.ByteArrayOutputStream;

public class YUV21Util {

    public static Bitmap loadMatrixBitmap(byte[] data, int width, int height, int orientation) {
        //先镜像翻转
        mirrorYUV21(data, width, height);
        //在转化为bitmap
        Bitmap bitmap = yuv21ToBitmap(data, width, height);
        //旋转图片
        Bitmap matrixBitmap = rotateBitmap(CameraPreviewManager.getInstance().loadDisplayOrientation(orientation), bitmap);
        return matrixBitmap;
    }

    /**
     * @param src    是原始yuv数组
     * @param width  原始图片的宽
     * @param height 原始图片的高
     **/
    public static void mirrorYUV21(byte[] src, int width, int height) {
        int i;
        int index;
        byte temp;
        int a, b;
        //mirror y
        for (i = 0; i < height; i++) {
            a = i * width;
            b = (i + 1) * width - 1;
            while (a < b) {
                temp = src[a];
                src[a] = src[b];
                src[b] = temp;
                a++;
                b--;
            }
        }

        // mirror u and v
        index = width * height;
        for (i = 0; i < height / 2; i++) {
            a = i * width;
            b = (i + 1) * width - 2;
            while (a < b) {
                temp = src[a + index];
                src[a + index] = src[b + index];
                src[b + index] = temp;

                temp = src[a + index + 1];
                src[a + index + 1] = src[b + index + 1];
                src[b + index + 1] = temp;
                a += 2;
                b -= 2;
            }
        }
    }

    /**
     * yuv转bitmap
     */

    public static Bitmap yuv21ToBitmap(byte[] data, int w, int h) {
        int plane = w * h;
        int[] colors = new int[plane];
        int yPos = 0, uvPos = plane;
        for (int j = 0; j < h; j++) {
            for (int i = 0; i < w; i++) {
                // YUV byte to RGB int
                final int y1 = data[yPos] & 0xff;
                final int u = (data[uvPos + 1] & 0xff) - 128;
                final int v = (data[uvPos] & 0xff) - 128;
                final int y1192 = 1192 * y1;
                int r = (y1192 + 1634 * v);
                int g = (y1192 - 833 * v - 400 * u);
                int b = (y1192 + 2066 * u);

                r = (r < 0) ? 0 : (Math.min(r, 262143));
                g = (g < 0) ? 0 : (Math.min(g, 262143));
                b = (b < 0) ? 0 : (Math.min(b, 262143));
                colors[yPos] = ((r << 6) & 0xff0000) |
                        ((g >> 2) & 0xff00) |
                        ((b >> 10) & 0xff);

                if ((yPos++ & 1) == 1) uvPos += 2;
            }
            if ((j & 1) == 0) uvPos -= w;
        }
        return Bitmap.createBitmap(colors, w, h, Bitmap.Config.RGB_565);
    }

    /**
     * @param data   字节数组
     * @param width  宽度
     * @param height 高度
     * @return bitmap bitmap对象
     */
    public static Bitmap onPreviewToBitmap(byte[] data, int width, int height) {
        final YuvImage image = new YuvImage(data, ImageFormat.NV21, width, height, null);
        ByteArrayOutputStream os = new ByteArrayOutputStream(data.length);
        if (!image.compressToJpeg(new Rect(0, 0, width, height), 100, os)) {
            return null;
        }
        byte[] tmp = os.toByteArray();
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
        return BitmapFactory.decodeByteArray(tmp, 0, tmp.length, options);
    }

    /**
     * 旋转拍照后的图片
     *
     * @param angle  角度
     * @param bitmap 原图
     * @return 旋转后的图片
     */
    public static Bitmap rotateBitmap(int angle, Bitmap bitmap) {
        //旋转图片 动作
        Matrix matrix = new Matrix();
        matrix.postRotate(angle);
        // 创建新的图片
        Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
                bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        return resizedBitmap;
    }

}
